package com.pkufinalproject.cleverreminder.controller;

import com.pkufinalproject.cleverreminder.hibernate.entity.Reminder;
import com.pkufinalproject.cleverreminder.hibernate.entity.RequestReminder;
import com.pkufinalproject.cleverreminder.hibernate.entity.RequestReminder;
import com.pkufinalproject.cleverreminder.hibernate.entity.User;
import org.apache.commons.lang.RandomStringUtils;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.List;

@RestController
@RequestMapping("request")
public class RequestReminderController {
    private final static SessionFactory sf = new Configuration().configure().buildSessionFactory();

    /**
     * 创建新的请求提醒
     * @param title 请求提醒的名称
     * @param ownerName 请求提醒的主人的用户名
     * @return 创建成功则返回token值，失败则返回文字提醒
     */
    @RequestMapping("register")
    public static String registerRegularReminder(String title, String ownerName) {
        User user = UserController.retrieveUser(ownerName);
        if (user == null) return "invalid owner name";
        RequestReminder requestReminder = retrieveRequestReminder(title, ownerName);
        if (requestReminder != null) return "request reminder already exists";
        Session session = sf.openSession();
        requestReminder = new RequestReminder();
        requestReminder.setTitle(title);
        requestReminder.setEnabled(true);
        requestReminder.setCreateTime(new Timestamp(System.currentTimeMillis()));
        requestReminder.setOwner(user);
        String token = requestReminder.generateToken();
        session.save(requestReminder);
        session.beginTransaction().commit();
        session.close();
        return token;
    }

    /**
     * 根据名称和用户将请求提醒disable掉
     * @param title 请求提醒的名称
     * @param ownerName 请求提醒的主人
     * @return 结果的文字说明
     */
    @RequestMapping("disable")
    public static String disableRequestReminder(String title, String ownerName) {
        Session session = sf.openSession();
        RequestReminder requestReminder = retrieveRequestReminder(title, ownerName);
        if (requestReminder == null) return "no request reminder found";
        requestReminder.setEnabled(false);
        session.update(requestReminder);
        session.beginTransaction().commit();
        session.close();
        return "disabled successfully";
    }

    /**
     * 根据名称和用户将请求提醒enable掉
     * @param title 请求提醒的名称
     * @param ownerName 请求提醒的主人
     * @return 结果的文字说明
     */
    @RequestMapping("enable")
    public static String enableRequestReminder(String title, String ownerName) {
        Session session = sf.openSession();
        RequestReminder requestReminder = retrieveRequestReminder(title, ownerName);
        if (requestReminder == null) return "no request reminder found";
        requestReminder.setEnabled(true);
        session.update(requestReminder);
        session.beginTransaction().commit();
        session.close();
        return "enabled successfully";
    }

    /***
     * 根据用户名找到用户的所有请求提醒
     * @param ownerName 用户名
     * @return json格式的请求提醒列表
     */
    @RequestMapping("retrieve_all")
    public static String strRetrieveAllRegularReminders(String ownerName) {
        List<RequestReminder> reminderList = retrieveAllRequestReminders(ownerName);
        return reminderList.toString();
    }

    public static List<RequestReminder> retrieveAllRequestReminders(String ownerName) {
        User user = UserController.retrieveUser(ownerName);
        if (user == null) return null;
        Session session = sf.openSession();
        Criteria criteria = session.createCriteria(RequestReminder.class)
                .add(Restrictions.like("owner", user));
        System.out.println("retrieve all " + ownerName);
        System.out.println(criteria.list());
        List<RequestReminder> reminderList = criteria.list();
        session.close();
        return reminderList;
    }

    /***
     * 根据用户名和提醒名找到一个提醒
     * @param title 提醒名
     * @param ownerName 用户名
     * @return 如找到则json格式的请求提醒信息，否则返回字符串格式的错误提醒。
     */
    @RequestMapping("retrieve")
    public static String strRetrieveRequestReminder(String title, String ownerName){
        RequestReminder requestReminder = retrieveRequestReminder(title, ownerName);
        if (requestReminder == null) return "no request reminder found";
        return requestReminder.toString();
    }

    public static RequestReminder retrieveRequestReminder(String title, String ownerName) {
        RequestReminder requestReminder = null;
        User user = UserController.retrieveUser(ownerName);
        if (user == null) return null;
        Session session = sf.openSession();
        Criteria criteria = session.createCriteria(RequestReminder.class)
                .add(Restrictions.like("owner", user))
                .add(Restrictions.like("title", title));
        List<RequestReminder> reminderList = criteria.list();
        if (!reminderList.isEmpty()) requestReminder = reminderList.get(0);
        session.close();
        return requestReminder;
    }

    /**
     * 处理要求发送提醒的请求
     * @param token 请求提醒的token
     * @param msg 请求的附加信息
     * @return 结果的文字说明
     */
    @RequestMapping("remind")
    public static String remind(String token, String msg) {
        // 在数据库中查找token对应的request_reminder记录
        RequestReminder requestReminder = null;
        Session session = sf.openSession();
        Criteria criteria = session.createCriteria(RequestReminder.class)
                .add(Restrictions.like("token", token));
        List<RequestReminder> reminderList = criteria.list();
        if (!reminderList.isEmpty()) requestReminder = reminderList.get(0);
        else return "invalid token";

        User owner = requestReminder.getOwner();
        String title = requestReminder.getTitle();
        if (!requestReminder.getEnabled()) return "remind is disabled";
        if (sendRemind(owner, title, msg)) return "remind sent successfully";
        return "remind sent error";
    }

    /**
     * 通过WebSocket向指定user发送一个请求提醒
     * @param user 目标User对象
     * @param title 请求提醒的名称
     * @param msg 请求提醒中附带的报文
     * @return bool变量，表示是否成功
     */
    public static boolean sendRemind(User user, String title, String msg) {
        JSONObject reqSend = new JSONObject();
        reqSend.put("type", "request_reminder");
        reqSend.put("title", title);
        reqSend.put("msg", msg);
        try {
            WebSocketServer ws = WebSocketServer.getWebSocketServerById(user.getId().toString());
            ws.sendMessage(reqSend.toString());
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }
}
